package net.wangds.jpa.comp;

import net.wangds.data.WithId;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.repository.MongoRepository;

import java.util.List;
import java.util.Optional;

/**
 * .
 * <p></p>
 *
 * @author 王东石 2020/5/15 20:56.
 */
public class AbstractMongoComp<T extends WithId<String>> extends MongoComp {


    protected final MongoRepository<T, String> repo;

    /**
     * 构造函数.
     * @param repo 数据库操作对象.
     */
    protected AbstractMongoComp(
            MongoRepository<T, String> repo
    ){
        this.repo = repo;
    }

    /**
     * 按照主键删除.
     * @param id 主键.
     */
    public void remove(String id){

        this.repo.deleteById(id);
        /*
        repo.findById(id).ifPresent(t->{
            t.setRemoved(RemovedEnum.REMOVED);
            repo.saveAndFlush(t);
        });
        */
    }

    /**
     * 逻辑删除.
     * @param target 删除目标.
     */
    @SuppressWarnings("unused")
    public void remove(T target){
        /*
        if(target==null|| StringUtils.isBlank(target.getId())){
            return;
        }
        remove(target.getId());
        */
        this.repo.delete(target);
    }

    /**
     * 永久删除target.
     * @param target 要删除的目标.
     */
    @SuppressWarnings("unused")
    public void erase(T target){
        this.repo.delete(target);
        //this.repo.flush();
    }

    /**
     * 永久删除target.
     * @param id 要删除的目标.
     */
    @SuppressWarnings("unused")
    public void erase(String id){
        this.repo.deleteById(id);
        //this.repo.flush();
    }

    /**
     * 新建或保存target.
     * @param target 要保存的目标.
     * @return 保存后的记录.
     */
    public T save(T target){
        return this.save(target, repo);
    }

    /**
     * 按照id查找.
     * @param id 主键.
     * @return 结果预期.
     */
    public Optional<T> findById(String id){
        return repo.findById(id);
    }

    /**
     * id对应的实体是否存在.
     * @param id 主键.
     * @return 实体.
     */
    @SuppressWarnings("unused")
    public boolean existsById(String id){
        return repo.existsById(id);
    }

    /**
     * 分页查询.
     * @param page 分页信息.
     * @return 当前页.
     */
    public Page<T> findAll(Pageable page){
        return repo.findAll(page);
    }

    /**
     * 获得所有记录.
     * @param sort 排序.
     * @return 所有记录.
     */
    @SuppressWarnings("unused")
    public List<T> findAll(Sort sort){
        return repo.findAll(sort);
    }

    public List<T> findAll() {
        return repo.findAll();
    }

    public Iterable<T> findAllById(Iterable<String> strings) {
        return repo.findAllById(strings);
    }

    public <S extends T> List<S> saveAll(Iterable<S> entities) {
        return repo.saveAll(entities);
    }

    public void deleteInBatch(Iterable<T> entities) {
        repo.deleteAll(entities);
    }

    public void deleteAllInBatch() {
        repo.deleteAll();
    }

    public T getOne(String s) {
        return repo.findById(s).orElse(null);
    }

    public <S extends T> List<S> findAll(Example<S> example) {
        return repo.findAll(example);
    }

    public <S extends T> List<S> findAll(Example<S> example, Sort sort) {
        return repo.findAll(example, sort);
    }


    public long count() {
        return repo.count();
    }

    public void deleteById(String s) {
        repo.deleteById(s);
    }

    public void delete(T entity) {
        repo.delete(entity);
    }

    public void deleteAll(Iterable<? extends T> entities) {
        repo.deleteAll(entities);
    }

    public void deleteAll() {
        repo.deleteAll();
    }

    public <S extends T> Optional<S> findOne(Example<S> example) {
        return repo.findOne(example);
    }

    public <S extends T> Page<S> findAll(Example<S> example, Pageable pageable) {
        return repo.findAll(example, pageable);
    }

    public <S extends T> long count(Example<S> example) {
        return repo.count(example);
    }

    public <S extends T> boolean exists(Example<S> example) {
        return repo.exists(example);
    }


}
